package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

// scanRepository рекурсивно сканирует директорию и записывает результаты в файл
func scanRepository(dir string, outputFile string) error {
	file, err := os.Create(outputFile)
	if err != nil {
		return fmt.Errorf("не удалось создать файл: %v", err)
	}
	defer file.Close()

	return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return fmt.Errorf("ошибка при доступе к пути %s: %v", path, err)
		}

		// Игнорируем папку .git
		if info.IsDir() && info.Name() == ".git" {
			return filepath.SkipDir
		}

		// Игнорируем бинарные файлы
		if !info.IsDir() && isBinaryFile(info.Name()) {
			return nil
		}

		relativePath, err := filepath.Rel(dir, path)
		if err != nil {
			return fmt.Errorf("ошибка при получении относительного пути для %s: %v", path, err)
		}

		if info.IsDir() {
			relativePath += string(os.PathSeparator)
		}

		// Записываем путь файла или директории
		if _, err := file.WriteString("Путь: " + relativePath + "\n"); err != nil {
			return fmt.Errorf("ошибка при записи пути %s в файл: %v", path, err)
		}

		// Если это файл, записываем его содержимое
		if !info.IsDir() {
			content, err := os.ReadFile(path)
			if err != nil {
				return fmt.Errorf("ошибка при чтении файла %s: %v", path, err)
			}
			if _, err := file.WriteString("Содержимое:\n" + string(content) + "\n\n"); err != nil {
				return fmt.Errorf("ошибка при записи содержимого файла %s: %v", path, err)
			}
		}

		return nil
	})
}

// isBinaryFile проверяет, является ли файл бинарным по его расширению
func isBinaryFile(filename string) bool {
	binaryExtensions := []string{".exe", ".dll", ".bin", ".dat", ".so", ".o", ".a"}
	for _, ext := range binaryExtensions {
		if strings.HasSuffix(filename, ext) {
			return true
		}
	}
	return false
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Использование: scan-repository <путь_к_репозиторию>")
		return
	}

	dir := os.Args[1]
	outputFile := filepath.Join(dir, "scan_result.txt")

	// Проверка, что указанный путь к директории существует
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		fmt.Printf("Указанный путь не существует: %s\n", dir)
		return
	}

	if err := scanRepository(dir, outputFile); err != nil {
		fmt.Printf("Ошибка при сканировании репозитория: %v\n", err)
		return
	}

	fmt.Printf("Сканирование завершено. Результаты записаны в файл: %s\n", outputFile)
}
